home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Precision Software Appli…tions Silver Collection 4
/
Precision Software Applications Silver Collection Volume 4 (1993).iso
/
stats
/
chadyn.exe
/
YFETCH.C
< prev
next >
Wrap
Text File
|
1988-12-15
|
22KB
|
710 lines
/************************************ YFETCH.C *******************************/
/*********************** (C) 1986,7,8 by JAMES A. YORKE **********************/
/********** ROUTINES in file: (the order in which they appear is important)
OpenFiles(argc,argv)
int argc;
char *argv[];
titleAndMode()
sets up the screen
NextArg() this is called when we want to check for the next argument on the
command line; if there is not one, we will set
argcGlob <= argNow ; otherwise if it is not a ':' command
(an entry beginning with a :), then we try to open it;
if it is a : command we set coloncommand = YES;
this is first called by OpenFiles
char *GetCrudeWord() this fetches one "word", a
collection of letters without white space; colon commands are
commands on the command line coloncommand is set
by NextArg();
char *GetGoodWord() gets next word, excluding comments.
int ParseString(niceString,givenstring,len,numstars)
The purpose of the following is to take commands and parse
them so they can be interpretted; "parse" means discarding
spaces and '*'s, and lowering the case of letters;
it gets string 'givenstring' of length up to LEN, deletes
spaces, changes Upper Case to lower case, puts resulting
digits and lower case letters and '-' and '+' signs
in niceString; it aborts if illegal
character is encountered; returns quality = -1 if bad char is
encountered or if string does not have '\0'; otherwise it
returns number of characters,
a number which could be 0; a colon is
accepted as a string terminator and later stuff is deleted;
char *niceString,*givenstring;
int len, *numstars;
int GetCommand() GetCommand fetches a string from the input device which is
either the keyboard or a disk file. It parses the string,
making sure it has only legal characters, eliminating
spaces and tabs and changing upper case letters to lower case.
If it determines that the string is legal, a 1 is returned,
otherwise 0; If it consists only of digits and possibly a
minus sign, it sticks the numerical value in "CodeName".
char *FindBeginning(docfile, HelpName, CodeName)
The routine is for fetching text from a document file whose
file pointer is "docfile"; it
looks at line after line; ignore lines that do not begin with
'*';
first truncate any line beginning with a * so that it does
not have any spaces between nontrivial characters, where
trivial means ' ' or '*' or tab;
then parse and decode the truncated
string; if the returned code == helpcode, we have the desired
line and the routine returns a pointer to the line;
otherwise it returns NULL.
FILE *docfile;
char *HelpName;
givehelp(StringReception, HelpName)
int StringReception;
char *HelpName;
int CheckForInt(string)
This function returns the integer value if string[] is a
positive integer other than -9999; if it is not an integer,
it returns -9999
char *string;
int GetMapName() This routine gets the map name and parses it and returns 1
if the name is acceptable; that does not guarantee that
a process by that name exists
OptionsHelp() called by interrupt()
getText(filename,option) this routine searches for a line beginning with an
asterisk and the rest of the line matches OPTION exactlyu.
it then prints out the following lines up to but not including
the next line that begins with an asterisk.
char *option, *filename;
int TestForPic() returns 1 if file ends in .pic, and otherwise returns 0
int keycheck() This routines checks to see if a key has been hit;
if not, it returns 0; if it has, it fetches the char and
returns it; it may have to check twice since extended codes
preface a non zero character with a zero.
The X Windows version uses a different routine.
******************************************************************************/
#define XINCLUDES
#include "yinclud.h"
#include <ctype.h>
static char *warning =
"*** Use upper case where appropriate; interrupts are CASE SENSITIVE *** \n";
OpenFiles(argc, argv)
int argc;
char *argv[];
{
#ifndef X11
colorPlanes = picAlloc(); /* allocates space for picture */
#endif
argNow = 0; /* the first entry (number 0) is the name of
the program at least on Unix systems */
argcGlob = argc;
argvGlob = argv;
#ifdef MAINFRAME
StandOutPut = fopen("OutScr", OPENFORWRITING);
/* Opens file for writing to the a standard
file in place of the screen */
StPrint = fopen("OutPrn", OPENFORWRITING);
/* Opens file for writing to the a standard
file in place of the standard printer */
#else
StOutPut = stdout;
StPrint = stdprn; /* this should be the only place stdout appears
*/
#endif
StInput = stdin;
NextArg();
titleAndMode(); /* set screen mode and plot title page */
}
/* ------------------------------------------------------------------------- */
titleAndMode() { /* set screen mode and plot title page */
#ifndef MAINFRAME
SetVidMode(); /* defined in YSCREEN.C */
#endif /* MAINFRAME */
jay();
#ifndef MAINFRAME
#ifndef unix
pause(1.2); /* pause for this number of seconds */
#endif /* UNIX */
#endif /* MAINFRAME */
}
/* ------------------------------------------------------------------------- */
NextArg() { /* this is called when we want to check for the
next argument on the command line; if there
is not one, we will set argcGlob <= argNow ;
otherwise if it is not a ':' command(an
entry beginning with a :), then we try to
open it; if it is a : command we set
coloncommand = YES; this is first called by
OpenFiles */
if(argcGlob > 0 && input != stdin && input != NULL)
fclose(input);
argNow++;
IsEndPIC = NO;
if(argcGlob > argNow) {/* notice that if argc(=argcGlob) is 5, then
the command line arguments are numbered
0,1,2,3,4 so if argNow is 5, we have
exceeded our list */
if(argvGlob[argNow][0] == ':') {
coloncommand = YES;
input = StInput;
}
else {
IsEndPIC = TestForPic(argvGlob[argNow]);
coloncommand = NO;
if((input = fopen(argvGlob[argNow], "r")) == NULL) {
input = StInput;
character_mode();
PRINT
"\n*********************************ERROR*******************************\n");
PRINT
" PROGRAM CANNOT FIND THE FILE %s WHICH YOU SPECIFIED \n"
,argvGlob[argNow]);
PRINT
" ON THE COMMAND LINE.\n");
PRINT
" IF THAT WAS SUPPOSED TO BE A COMMAND, PRECEDE IT WITH A ':' \n");
PRINT
"*****************************PROGRAM TERMINATES***********************\n");
PRINT
" J.A.Y.\n\n\n");
exit(1);
}
} /* end else */
}
else {
coloncommand = NO;
status = 0; /* this means the disk files are finished */
input = StInput;
}
}
/* ------------------------------------------------------------------------- */
/* GETCRUDEWORD - fetches and returns one "word", a collection of letters without
* white space; colon commands are commands on the command line and are
* preceded by ':'; coloncommand is set by NextArg().
* Return NULL on end of file and a pointer to the next word otherwise.
*/
char *GetCrudeWord()
{
static char CrudeString[MAXCHAR+1];
char *word = CrudeString;
if(coloncommand == YES) {
(void) strcpy(CrudeString, &argvGlob[argNow][1]);
PRINT ":%s", CrudeString);
ret_erase_line(2);
NextArg();
} else {
#ifdef X11
if(input == StInput
&& sscanf(xwfgets(), "%s", CrudeString) == EOF ||
input != StInput
&& fscanf(input, "%s", CrudeString) == EOF) {
PRINT "EOF\n");
CrudeString[0] = '\0';
word = NULL;
}
#else
if(abortEnter() == YES)
CrudeString[0] = '\0';
else if(fscanf(input, "%s", CrudeString) == EOF) {
PRINT "EOF\n");
word = NULL;
}
#endif
}
return(word);
}
/* ------------------------------------------------------------------------- */
/* GETGOODWORD - get next crude word excluding comments.
* Comments are delimited by slash/asterisk pairs SEPARATED BY WHITE SPACE.
* When the end of the input is detected, we return the word "fileend".
*/
char *GetGoodWord()
{
char *CrudeString;
CrudeString = GetCrudeWord();
if(strcmp(CrudeString, "/*") == 0) {
do
CrudeString = GetCrudeWord();
while(CrudeString != NULL && strcmp(CrudeString, "*/") != 0);
if(CrudeString != NULL && strcmp(CrudeString, "*/") == 0)
CrudeString = GetCrudeWord();
}
return(CrudeString == NULL ? "fileend" : CrudeString);
}
/* ------------------------------------------------------------------------- */
#ifdef MS
/* INDEX - works like the Unix subroutine of the same name which the MS C
* library is lacking.
*/
char *index(s, ch)
register char *s;
char ch;
{
if(s == NULL)
return(NULL);
while(*s != '\0' && *s != ch)
s++;
return(*s == ch ? s : NULL);
}
#endif /* MS */
/* ------------------------------------------------------------------------- */
/* PARSESTRING - Take commands and parse them so
* they can be interpreted; "parse" means discarding spaces and '*'s, and
* lowering the case of letters; it gets GIVENSTRING of length up
* to LEN, deletes spaces, changes Upper Case to lower case, puts
* resulting digits and lower case letters and '-' and '+' signs in
* NICE; it aborts if illegal character is encountered; returns -1
* if bad char is encountered or if GIVENSTRING does not have
* '\0'; otherwise it returns number of characters, a number which could
* be 0; a colon is accepted as a string terminator and later stuff is
* deleted. Numstars is set to the number of asterisks that were seen.
*/
int ParseString(nicestring, givenstring, len, numstars)
register char *nicestring;
char *givenstring;
int len;
int *numstars;
{
static char *charlist = "+-_[]{}();/";
register char *g; /* indexes givenstring */
register int ch;
int starcount = 0;
int j;
/* check for a NUL to terminate GIVENSTRING and for ascii characters.
* This assures that the ctype(3) macros work properly.
*/
g = givenstring;
for(j = 0; j < len && isascii(*g) && *g != '\0'; j++)
g++;
if(j == len || !isascii(*g)) {
*numstars = 0;
return(-1); /* no '\0' anywhere or a nonascii character */
}
/* Translate upper case to lower case, skip spaces and stars,
* count stars, and copy allowable punctuation.
*/
for(g = givenstring; *g != '\0'; g++) {
ch = *g;
if(isupper(ch)) /* A-Z -> a-z */
#ifdef _tolower
*nicestring++ = _tolower(ch);
#else
*nicestring++ = tolower(ch);
#endif
else if(isalnum(ch)) /* a-z or 0-9 */
*nicestring++ = ch;
else if(index(charlist, ch) != NULL) /* allowed punctuation */
*nicestring++ = ch;
else if(ch == '*') /* skip stars */
starcount++;
else if(!isspace(ch)) /* skip whitespace */
break;
}
if(*g != '\0') {
if(ch != ':') /* bad character */
return(-1);
else if(g[1] != '\0') {
PRINT "remainder of line after colon is ignored\n");
beep();
}
}
*nicestring = '\0';
*numstars = starcount;
return((int) (g - givenstring));
}
/* ------------------------------------------------------------------------- */
/* GETCOMMAND - fetch a string from the input device which is either
* the keyboard or a disk file. Parse the string, making sure it has
* only legal characters, eliminating spaces and tabs and changing upper
* case letters to lower case. If the string is legal,
* a 1 is returned, otherwise 0. The string is copied into CodeName.
* On EOF the string "fileend" is copies into CodeName.
*/
int GetCommand(CodeName)
char *CodeName;
{
int StringReception;
char *CrudeString;
char HelpName[MAXCHAR];
int numStars; /* number of asterisks in input */
CrudeString = GetGoodWord();
if(CrudeString[0] == '\n' || CrudeString[0] == '\0') {
/* the zero occurs when a comment line is
deleted */
CodeName[0] = '\0';
return(0);
}
StringReception = ParseString(CodeName, CrudeString, 20, &numStars);
/* This puts the received string into a
standard format and sticks the revised
version in CodeName[] */
if(input == StInput) {
erase_line();
ret_erase_line(1);
}
if(StringReception < 0) {
PRINT "Bad input string; try again\n");
StringReception = 0;
} else if(StringReception > 0) {
/* if there is one asterisk in the string
entered, that indicates help is needed; the
spaces and asterisks have deleted and the
result is code; numStars is the number of
asterisks; their positions do not count */
if(numStars > 1) {
PRINT "too many asterisks \n");
StringReception = 0;
} else if(numStars == 1) {
(void) strcpy(HelpName, CodeName);
givehelp(StringReception, HelpName, CodeName);
StringReception = 0;
} else
StringReception = 1;
} else
StringReception = 0;
return(StringReception);
}
/* ------------------------------------------------------------------------- */
/* FINDBEGINNING - Copy text from the document file, ignoring lines
* that do not begin with '*'.
* First truncate any line beginning with a * so that it does not have any
* spaces between nontrivial characters, where trivial means ' ' or '*' or
* tab; then parse and decode the truncated string; if the returned code
* == helpcode, we have the desired line and the routine quits, returning
* a pointer to the desired line; it returns NULL at EOF or other problem.
*/
char *FindBeginning(docfile, HelpName, CodeName)
FILE *docfile;
char *HelpName, *CodeName;
{
static char docstr[MAXCHAR+1];
char line[MAXCHAR+1], *s, *cp;
int k;
int junk;
while((cp = fgets(docstr, MAXCHAR, docfile)) != NULL) {
s = docstr;
if(*s == '*') {
while(*s != '\0' && isspace(*s)) /* skip whitespace */
s++;
for(k = 0; *s != '\0' && !isspace(*s); k++)
line[k] = *s++;
line[k] = '\0';
if(ParseString(CodeName, line, 20, &junk) > 0 &&
strcmp(HelpName, CodeName) == 0)
break;
}
}
return(cp);
}
/* ------------------------------------------------------------------------- */
givehelp(StringReception, HelpName, CodeName)
int StringReception;
char *HelpName, *CodeName;
{
#ifndef X11
char Chr;
#endif
char *firstline, *cp;
char docstr[MAXCHAR+1];
FILE *docfile;
if(StringReception == 0) {
erase_line();
printf("To get help on any command, type * and then the command, then <return>\n");
erase_line();
printf("Example: *DOTS<return> (no spaces)");
ret_erase_line(2);
return;
}
if((docfile = fopen("commands.doc", "r")) == NULL) {
PRINT "can't open document file for commands\n");
return;
}
if((firstline = FindBeginning(docfile, HelpName, CodeName)) == NULL) {
erase_line();
printf("Sorry-- no help available for what you entered.");
ret_erase_line(2);
return;
}
printf(firstline);
while((cp = fgets(docstr, MAXCHAR, docfile)) != NULL) {
if(docstr[0] == '*' && docstr[1] == '*') { /* temporary stop */
printf("PAUSE: hit Esc to quit; hit any other key for related info.\r");
#ifdef X11
putchar('\n');
if(awaitkey(0) == ESC)
break;
#else
/* keep trying until a character is entered */
while((Chr = keycheck()) == 0);
printf( " \r");
if(Chr == ESC)
break;
#endif
printf(docstr + 2);
} else if(docstr[0] == '*') {
break;
} else if(docstr[0] != '.' && !isblank(docstr)) {
printf(docstr);
}
}
if(cp == NULL) {
printf("end of file \n");
erase_line();
return;
}
fclose(docfile);
}
/* ------------------------------------------------------------------------- */
/* CHECKFORINT - return the integer value in the string S if it contains
* a valid integer other than -9999. Otherwise return -9999.
*/
int CheckForInt(s)
register char *s;
{
int isnegative = 0;
int value = 0;
if(*s == '-') {
isnegative = 1;
s++;
}
while(isdigit(*s)) {
value = value * 10 + *s - '0';
s++;
}
if(isnegative)
value = -value;
return(*s == '\0' ? value : -9999);
}
/* ------------------------------------------------------------------------- */
/* GETMAPNAME - place the map name in global variable MapName.
* Return 1 if the name is acceptable and 0 otherwise.
* The routine does not guarantee that a process by that name exists.
* To prevent an infinite loop when reading from a file, we return the
* name "xx" to cause the program to exit if an eof of file is detected.
*/
int GetMapName()
{
int StringReception;
char *CrudeString;
int junk;
CrudeString = GetGoodWord();
if(strcmp(CrudeString, "fileend") == 0) {
(void) strcpy(MapName, "xx");
StringReception = 1;
} else
StringReception = ParseString(MapName, CrudeString, 20, &junk);
if(StringReception < 0)
PRINT "Try again\n");
return(StringReception > 0);
}/* ------------------------------------------------------------------------- */
OptionsHelp() /* called by interrupt() */
{
char *option,*note;
char keystroke[2];
int kk;
scr_rowcol(15,0);
erase_line();
note =
"Hit a key for that interrupt's description or a key for an interrupt menu \n"
; PRINT note);
PRINT warning);
erase_line();
ret_erase_line(7);
#ifdef X11
kk = awaitkey(0);
#else
while((kk = keycheck()) == 0); /* wait for input */
#endif
scr_rowcol(15,0);
erase_line();
switch(kk) {
case '+': /* to declare picture finished */
case '-':
case Home:
case PgUp:
option = "+";
break;
case 'e':
case 'E':
option = "e";
break;
case 's':
case F1:
case F2:
case F3:
case F4:
case F10:
option = "s";
break;
case F5:
case F6:
case F7:
case F8:
case F9: /* we need an ascii character and though F has
* nothing do with color, it'll do for now */
option = "F";
break;
case 'x':
case 'y':
option = "x";
break;
case ESC:
option = "Esc";
break;
case DOWN:
case UP:
case RIGHT:
case LEFT:
case End:
case PgDn:
option = "DOWN";
break;
default:
if(isdigit(kk))
option = "0";
else {
keystroke[0] = kk;
keystroke[1] = '\0';
option = keystroke;
}
break;
}
if(option != NULL)
getText("yintrpt.doc", option);
erase_line();
ret_erase_line(1);
PRINT "Hit r to refresh the screen.\n");
erase_line();
ResetScrnLineAtTop();
}
/* ------------------------------------------------------------------------- */
/* GETTEXT - search for a line beginning with an asterisk and the rest of which
* exactly matches the string given by OPTION.
*/
getText(filename, option)
char *option,
*filename;
{
FILE *fp;
char *ptr; /* used to see if we get to end of file */
char string[MAXCHAR+1];
if((fp = fopen(filename, "r")) == NULL) {
erase_line();
PRINT "\n Cannot locate text file %s \n", filename);
return;
}
/* Read lines until EOF */
while((ptr = fgets(string, MAXCHAR, fp)) != NULL) {
deleteLF(string); /* delete trailing newline */
if(string[0] == '*' && strcmp(&string[1], option) == 0) {
/* have starting line so print info */
while(fgets(string, MAXCHAR, fp) != NULL &&
string[0] != '*') {
erase_line();
PRINT string);
}
break;
}
}
if(ptr == NULL) {
erase_line();
PRINT " ********** No information found **********\n");
PRINT warning);
erase_line();
}
fclose(fp);
return;
}
/* ------------------------------------------------------------------------ */
/* DELETELF - terminate the given string at the first newline. */
deleteLF(s)
register char *s;
{
if(s == NULL)
return;
while(*s != '\n' && *s != '\0')
s++;
if(*s == '\n')
*s = '\0';
return;
}
/* ------------------------------------------------------------------------- */
/* ISBLANK - return 1 if the string consists only of whitespace, 0 otherwise. */
int isblank(s)
register char *s;
{
while(isspace(*s))
s++;
return(*s == '\0');
}
/* ------------------------------------------------------------------------- */
/* TESTFORPIC - Returns 1 if S ends in ".pic" or ".PIC". */
int TestForPic(s)
register char *s;
{
while(*s != '.' && *s != '\0')
s++;
return(strcmp(s, ".pic") == 0 || strcmp(s, ".PIC") == 0);
}
/* X Windows has its own set of keycodes which we handle in ywindows.c */
#ifndef X11
/********************************** YKEYCHK.C ********************************/
/********************* (C) 1986,7,8 by JAMES A. YORKE ************************/
/***************************************************
ASCII character codes
can be found in Microsoft C Compiler manual, p. 175
Some ascii codes -- see BASIC manual appendix G
48-57: 0,1,...,9
65-90: A,...,Z
97-122: a,...,z
Notice above defined codes 71,72,73,75,77,79,80,81
G H I K M O P Q
Some Extended Codes --preceeded by a character 0
120-131: Alt 1,2,...,0,-,=
59-68: F1-F10
84-93: SHIFTED F1-F10
94-103 Ctrl F1-F10
104-103 Alt F1-F10
16-25 Alt Q,W,E,R,T,Y,U,I,O,P
30-38 Alt A S D F G H J K L
44-50 Alt Z X C V B N M
****************************************************/
int keycheck() { /* This routines checks to see if a key has
been hit; if not, it returns 0; if it has,
it fetches the char and returns it; it may
have to check twice since extended codes
preface a non zero character with a zero; */
int ch;
if(ChkKeyStatus() == 0)
return(0);
if((ch = ci()) != 0) /* ci is a desmet routine */
return(ch);
return(-ci());
}
#endif